(function (prototype) {
  function bind(context, ...outerArgs) {
    var that = this; // that -> add.bind(null,1,2)


    // add.bind(null, 1, 2).bind(null, 3, 4)() 执行
    // ↑等价于↓
    // add.bind(null,1,2).call(null,3,4,...args)
    return function(...args) {
      // this -> null 这里的this没用
      // args -> 3,4,...args
      // that -> add
      // add.call(null/*←第一bind的this*/,1,2,(args -> 3,4,...args))
      return that.call(context, ...outerArgs, ...args);
    };

    /** 故可以得出结论:
     * fnX.bind(this1,a,b).bind(this2,c,d).bind(this3,e,f) === fnX.bind(this1,a,b,c,d,e,f)*/
  }

  prototype.bind = bind;
})(Function.prototype);

function add(...args){
  console.log('this:',this);
  return eval(args.join('+'));
}

console.log(add(1, 2, 3, 4)); // 10

console.log(add.bind(null, 1, 2).bind(null, 3, 4)()); // 10


// console.log(add.bind({a:1,b:2}, 1, 2).bind(null, 3, 4).bind(null,5,6)()); // this: { a: 1, b: 2 }  21
